package com.cal.utms.model.maintenance;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.cal.utms.dao.maintenance.CustomerDaoImpl;
import com.cal.utms.dto.maintenance.CustomerBankAccountDto;
import com.cal.utms.dto.maintenance.CustomerContactPersonsDto;
import com.cal.utms.dto.maintenance.CustomerDto;
import com.cal.utms.dto.maintenance.CustomerEmailDto;
import com.cal.utms.dto.maintenance.CustomerJointApplicantDto;
import com.cal.utms.entity.Customer;
import com.cal.utms.entity.CustomerBankAccount;
import com.cal.utms.entity.CustomerCodeSerial;
import com.cal.utms.entity.CustomerContactPerson;
import com.cal.utms.entity.CustomerEmail;
import com.cal.utms.entity.CustomerJointAppicant;

public class CustomerModel {

	protected CustomerDaoImpl customerDao = new CustomerDaoImpl();

	public String saveCustomer(CustomerDto customerBean, String emails, String bankAccounts, String jointApplicans, String contactPersons) {

		if (validateNic(customerBean, jointApplicans)) {
			Customer customer = createCustomerModle(customerBean, emails, bankAccounts, jointApplicans, contactPersons);
			Object object = customerDao.saveCustomer(customer);
			if (object instanceof Integer) {
				customerBean.setId((Integer) object);
				customerBean.setSuccess(true);
			} else {
				customerBean.setSuccess(false);
				customerBean.setResultMsg("There is some error returned from the server.");
			}
		} else {
			customerBean.setSuccess(false);
			customerBean.setResultMsg("Duplicate NIC/ Passport No. fund");
		}
		return customerBean.getCode();

	}

	private boolean validateNic(CustomerDto customerBean, String jointApplicans) {

		boolean validate = false;
		if (customerBean.getAccountType().equals("C")) {
			validate = true;
		} else if (customerBean.getAccountType().equals("I")) {
			Customer preCustomer = customerDao.getCustomerByNIC(customerBean.getNicPassport(), customerBean.getAccountType());
			if (preCustomer != null)
				validate = false;
			else
				validate = true;
		} else if (customerBean.getAccountType().equals("J")) {
			List<String> nicList = new ArrayList<String>();
			nicList.add(customerBean.getNicPassport());
			if (jointApplicans != null) {
				jointApplicans = "{ \"jointApplicans\" : ".concat(jointApplicans) + " }";
				try {
					JSONObject jsonObject = new JSONObject(jointApplicans);
					JSONArray jArray = jsonObject.getJSONArray("jointApplicans");
					for (int i = 0; i < jArray.length(); i++) {
						JSONObject jObj = jArray.getJSONObject(i);
						nicList.add(jObj.getString("jaNicPassport"));
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
			boolean flag = false;
			validate = true;
			for (String nic : nicList) {
				List<Customer> customers = customerDao.getJointCustomerByNIC(nic, "J");
				if (customers.size() > 0) {
					for (Customer customer : customers) {
						List<String> nicListB = new ArrayList<String>();
						nicListB.add(customer.getNicPassport());
						for (CustomerJointAppicant appicant : customer.getCustomerJointAppicants()) {
							nicListB.add(appicant.getJaNicPassport());
						}
						flag = compareNic(nicList, nicListB);
						if (flag)
							validate = !flag;
					}
				}
			}
		}
		return validate;
	}

	private boolean compareNic(List<String> nicList, List<String> nicListB) {

		boolean stat = false;

		if (nicList.size() == nicListB.size()) {
			Collection<String> similar = new HashSet<String>(nicList);
			similar.retainAll(nicListB);
			if (similar.size() == nicList.size())
				stat = true;// equal
			else
				stat = false;// not equal
		} else {
			stat = false; // not equal
		}
		return stat;
	}

	public Customer createCustomerModle(CustomerDto customerBean, String emails, String bankAccounts, String jointApplicans, String contactPersons) {

		Customer customer = new Customer();
		String customer_surname = null;
		List<CustomerEmail> customerEmails = new ArrayList<CustomerEmail>();
		List<CustomerBankAccount> customerBankAccounts = new ArrayList<CustomerBankAccount>();
		List<CustomerJointAppicant> customerJointAppicants = new ArrayList<CustomerJointAppicant>();
		List<CustomerContactPerson> customerContactPersons = new ArrayList<CustomerContactPerson>();

		customer.setAccountType(customerBean.getAccountType());
		customer.setResidential(customerBean.getResidential());
		customer.setFmId(customerBean.getFmId() != 0 ? customerBean.getFmId() : null);
		customer.setCustomerType(customerBean.getCustomerType());

		if (customerBean.getAccountType().equals("C")) {
			customer_surname = customerBean.getOrganizationName().trim();
			customer.setSurname(customer_surname);
			customer.setNicPassport(customerBean.getBusinessRegNo());
			customer.setCorrespondingAddress(customerBean.getBusinessAddress());

			if (contactPersons != null) {
				contactPersons = "{ \"contactPersons\" : ".concat(contactPersons) + " }";
				try {
					JSONObject jsonObject = new JSONObject(contactPersons);
					JSONArray jArray = jsonObject.getJSONArray("contactPersons");
					for (int i = 0; i < jArray.length(); i++) {
						JSONObject jObj = jArray.getJSONObject(i);
						CustomerContactPerson contactPerson = new CustomerContactPerson();
						contactPerson.setName(jObj.getString("name"));
						contactPerson.setDesignation(jObj.getString("designation"));
						contactPerson.setEmail(jObj.getString("email"));
						contactPerson.setFax(jObj.getString("fax"));
						contactPerson.setPhone(jObj.getString("phone"));
						contactPerson.setCustomer(customer);
						customerContactPersons.add(contactPerson);
					}
				} catch (JSONException e) {
					e.printStackTrace();
				}
			}
		} else {
			if (!emails.equals("null")) {
				String[] string_email = emails.split(",");
				for (int i = 0; i < string_email.length; i++) {
					CustomerEmail email = new CustomerEmail();
					email.setEmail(string_email[i].replaceAll("^\"|\"$", ""));
					email.setCustomer(customer);
					customerEmails.add(email);
				}
			}

			if (customerBean.getAccountType().equals("J")) {
				if (jointApplicans != null) {
					jointApplicans = "{ \"jointApplicans\" : ".concat(jointApplicans) + " }";
					try {
						JSONObject jsonObject = new JSONObject(jointApplicans);
						JSONArray jArray = jsonObject.getJSONArray("jointApplicans");
						for (int i = 0; i < jArray.length(); i++) {
							JSONObject jObj = jArray.getJSONObject(i);
							CustomerJointAppicant appicant = new CustomerJointAppicant();
							appicant.setJaName(jObj.getString("jaName"));
							appicant.setJaNicPassport(jObj.getString("jaNicPassport"));
							appicant.setJaAddress(jObj.getString("jaAddress"));
							appicant.setJaEmail(jObj.getString("jaEmail"));
							appicant.setJaFax(jObj.getString("jaFax"));
							appicant.setJaPhone(jObj.getString("jaPhone"));
							appicant.setCustomer(customer);
							customerJointAppicants.add(appicant);
						}
					} catch (JSONException e) {
						e.printStackTrace();
					}
				}
			}
			customer_surname = customerBean.getSurname().trim();
			customer.setTitle(customerBean.getTitle());
			customer.setInitials(customerBean.getInitials());
			customer.setSurname(customer_surname);
			customer.setDenotedByInitials(customerBean.getDenotedByInitials());
			customer.setNicPassport(customerBean.getNicPassport());
			customer.setCorrespondingAddress(customerBean.getCorrespondingAddress());
			customer.setGeneralAddress(customerBean.getGeneralAddress());
			customer.setPhone(customerBean.getPhone());
			customer.setMobileNo(customerBean.getMobileNo());
			customer.setFax(customerBean.getFax());
		}

		if (bankAccounts != null) {
			bankAccounts = "{ \"bankAccounts\" : ".concat(bankAccounts) + " }";
			try {
				JSONObject jsonObject = new JSONObject(bankAccounts);
				JSONArray jArray = jsonObject.getJSONArray("bankAccounts");
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject jObj = jArray.getJSONObject(i);
					CustomerBankAccount account = new CustomerBankAccount();
					if (jObj.getInt("id") != 0) {
						account.setId(jObj.getInt("id"));
					}
					account.setAccountNo(jObj.getString("accountNo"));
					account.setBranch(jObj.getString("branch"));
					account.setNameOfBank(jObj.getString("nameOfBank"));
					account.setCustomer(customer);
					customerBankAccounts.add(account);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		customer.setCorresInst(customerBean.getCorresInst());
		customer.setCorresPost(customerBean.getCorresPost());
		customer.setCorresEmail(customerBean.getCorresEmail());
		customer.setCorresFax(customerBean.getCorresFax());
		customer.setBankInstrution(customerBean.getBankInstrution());

		customer.setCustomerEmails(customerEmails);
		customer.setCustomerJointAppicants(customerJointAppicants);
		customer.setCustomerContactPersons(customerContactPersons);

		if (customerBean.getId() == null) {
			String customer_code = getCustomerCode(customerBean.getAccountType().toUpperCase(), customerBean.getResidential().toUpperCase(),
					customer_surname.toUpperCase().charAt(0));
			customerBean.setCode(customer_code);
			customer.setCode(customer_code);
			customer.setCustomerBankAccounts(customerBankAccounts);
		} else {
			CustomerDaoImpl daoImpl = new CustomerDaoImpl();
			Customer preCustomer = daoImpl.getCustomerById(customerBean.getId());
			if (!preCustomer.getAccountType().toUpperCase().equals(customerBean.getAccountType().toUpperCase())
					|| !preCustomer.getResidential().toUpperCase().equals(customerBean.getResidential().toUpperCase())
					|| preCustomer.getSurname().trim().toUpperCase().charAt(0) != customer_surname.toUpperCase().charAt(0)) {
				String customer_code = getCustomerCode(customerBean.getAccountType().toUpperCase(), customerBean.getResidential().toUpperCase(), customer_surname.toUpperCase()
						.charAt(0));
				customerBean.setCode(customer_code);
				customer.setCode(customer_code);
			} else {
				customerBean.setCode(preCustomer.getCode());
				customer.setCode(preCustomer.getCode());
			}
		}

		return customer;
	}

	private String getCustomerCode(String accountType, String residential, char charAt) {
		CustomerDaoImpl customerDaoImpl = new CustomerDaoImpl();
		CustomerCodeSerial codeSerial = customerDaoImpl.getCustomerCode(accountType, residential, String.valueOf(charAt));
		String serial = String.valueOf(codeSerial.getSerial());
		if (serial.length() == 1) {
			serial = "000" + serial;
		} else if (serial.length() == 2) {
			serial = "00" + serial;
		} else if (serial.length() == 3) {
			serial = "0" + serial;
		}
		String code = accountType + residential + String.valueOf(charAt) + serial;
		return code;
	}

	public List<CustomerDto> createCustomerBeanList(List<Customer> customers) {
		List<CustomerDto> customerBeans = new ArrayList<CustomerDto>();
		CustomerDto customerBean = null;
		for (Customer customer : customers) {
			customerBean = new CustomerDto();
			customerBean.setId(customer.getId());
			customerBean.setAccountType(customer.getAccountType());
			customerBean.setCode(customer.getCode());
			customerBean.setCustomerType(customer.getCustomerType());
			customerBean.setResidential(customer.getResidential());
			customerBean.setFmId(customer.getFmId() == null ? 0 : customer.getFmId());
			if (customer.getAccountType().equals("C")) {
				customerBean.setBusinessAddress(customer.getCorrespondingAddress());
				customerBean.setOrganizationName(customer.getSurname());
				customerBean.setBusinessRegNo(customer.getNicPassport());
				customerBean.setSurname(customer.getSurname());
			} else {
				customerBean.setCorrespondingAddress(customer.getCorrespondingAddress());
				customerBean.setDenotedByInitials(customer.getDenotedByInitials());
				customerBean.setFax(customer.getFax());
				customerBean.setGeneralAddress(customer.getGeneralAddress());
				customerBean.setInitials(customer.getInitials());
				customerBean.setNicPassport(customer.getNicPassport());
				customerBean.setPhone(customer.getPhone());
				customerBean.setMobileNo(customer.getMobileNo());
				customerBean.setSurname(customer.getSurname());
				customerBean.setTitle(customer.getTitle());
			}
			customerBean.setCorresEmail(customer.getCorresEmail());
			customerBean.setCorresFax(customer.getCorresFax());
			customerBean.setCorresPost(customer.getCorresPost());
			customerBean.setCorresInst(customer.getCorresInst());
			customerBean.setBankInstrution(customer.getBankInstrution());
			customerBeans.add(customerBean);
		}
		return customerBeans;
	}

	public static List<CustomerBankAccountDto> createAccountBeans(List<CustomerBankAccount> accounts) {
		List<CustomerBankAccountDto> accountBeans = new ArrayList<CustomerBankAccountDto>();
		CustomerBankAccountDto accountBean = null;
		for (CustomerBankAccount customerBankAccount : accounts) {
			accountBean = new CustomerBankAccountDto();
			accountBean.setAccountNo(customerBankAccount.getAccountNo());
			accountBean.setBranch(customerBankAccount.getBranch());
			accountBean.setId(customerBankAccount.getId());
			accountBean.setNameOfBank(customerBankAccount.getNameOfBank());
			accountBeans.add(accountBean);
		}
		return accountBeans;
	}

	public static List<CustomerEmailDto> createEmailBeans(List<CustomerEmail> emailByCustomerId) {
		List<CustomerEmailDto> customerEmailDtos = new ArrayList<CustomerEmailDto>();
		for (CustomerEmail customerEmail : emailByCustomerId) {
			CustomerEmailDto dto = new CustomerEmailDto();
			dto.setEmail(customerEmail.getEmail());
			dto.setId(customerEmail.getId());
			customerEmailDtos.add(dto);
		}
		return customerEmailDtos;
	}

	public List<CustomerJointApplicantDto> getjointApplicant(int customer_id) {
		List<CustomerJointApplicantDto> jointApplicantDtos = new ArrayList<CustomerJointApplicantDto>();
		List<CustomerJointAppicant> appicants = customerDao.getAppicntByCustomerId(customer_id);
		for (CustomerJointAppicant customerJointAppicant : appicants) {
			CustomerJointApplicantDto applicantDto = new CustomerJointApplicantDto();
			applicantDto.setId(customerJointAppicant.getId());
			applicantDto.setJaName(customerJointAppicant.getJaName());
			applicantDto.setJaNicPassport(customerJointAppicant.getJaNicPassport());
			applicantDto.setJaAddress(customerJointAppicant.getJaAddress());
			applicantDto.setJaEmail(customerJointAppicant.getJaEmail());
			applicantDto.setJaFax(customerJointAppicant.getJaFax());
			applicantDto.setJaPhone(customerJointAppicant.getJaPhone());
			jointApplicantDtos.add(applicantDto);
		}
		return jointApplicantDtos;
	}

	public List<CustomerContactPersonsDto> getContactPerson(int customer_id) {
		List<CustomerContactPersonsDto> contactPersonsDtos = new ArrayList<CustomerContactPersonsDto>();
		List<CustomerContactPerson> contactPersons = customerDao.getContactPersonByCusId(customer_id);
		for (CustomerContactPerson customerContactPerson : contactPersons) {
			CustomerContactPersonsDto contactPersonsDto = new CustomerContactPersonsDto();
			contactPersonsDto.setName(customerContactPerson.getName());
			contactPersonsDto.setDesignation(customerContactPerson.getDesignation());
			contactPersonsDto.setEmail(customerContactPerson.getEmail());
			contactPersonsDto.setFax(customerContactPerson.getFax());
			contactPersonsDto.setPhone(customerContactPerson.getPhone());
			contactPersonsDto.setId(customerContactPerson.getId());
			contactPersonsDtos.add(contactPersonsDto);
		}
		return contactPersonsDtos;
	}

	public String updateCustomer(CustomerDto customerBean, String emails, String bankAccounts, String jointApplicans, String contactPersons) {
		List<CustomerBankAccount> customerBankAccounts = new ArrayList<CustomerBankAccount>();
		Customer customer = createCustomerModle(customerBean, emails, null, jointApplicans, contactPersons);
		customer.setId(customerBean.getId());
		if (bankAccounts != null) {
			bankAccounts = "{ \"bankAccounts\" : ".concat(bankAccounts) + " }";
			try {
				JSONObject jsonObject = new JSONObject(bankAccounts);
				JSONArray jArray = jsonObject.getJSONArray("bankAccounts");
				for (int i = 0; i < jArray.length(); i++) {
					JSONObject jObj = jArray.getJSONObject(i);
					CustomerBankAccount account = new CustomerBankAccount();
					if (jObj.getInt("id") != 0) {
						account.setId(jObj.getInt("id"));
					}
					account.setAccountNo(jObj.getString("accountNo"));
					account.setBranch(jObj.getString("branch"));
					account.setNameOfBank(jObj.getString("nameOfBank"));
					account.setCustomer(customer);
					customerBankAccounts.add(account);
				}
			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
		Object object = customerDao.updateCustomer(customer, customerBankAccounts);
		return object.toString();
	}

}
